package com.serviceprovider.business.module.sp.user;

//~--- non-JDK imports --------------------------------------------------------

import com.serviceprovider.business.module.common.Page;
import com.serviceprovider.business.module.user.model.forms.EditUserForm;
import com.serviceprovider.business.module.user.model.forms.ViewUserForm;
import com.serviceprovider.business.module.user.model.impl.User;
import com.serviceprovider.business.module.user.model.impl.UserManager;
import com.serviceprovider.business.module.user.model.impl.UserSearchCriteria;
import com.serviceprovider.business.module.user.model.interfaces.IElements;
import com.serviceprovider.business.utility.ApplicationConfigProperties;
import com.serviceprovider.business.utility.SecurityContextUser;
import com.serviceprovider.business.utility.maintenance.settings.RoleUtils;

import org.apache.commons.lang.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.validation.BindingResult;
import org.springframework.web.servlet.ModelAndView;

//~--- JDK imports ------------------------------------------------------------

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @Leonardo A. Auer
 * @since 04/11/2011
 */

/**
 * Implementation of UserManager class.
 * This class manages all request received from
 * user controller when user connected is ROLE_SERVICE_PROVIDER
 */
@Repository("spManager")
public class ServiceProviderManager extends UserManager {
    @Autowired
    private ApplicationConfigProperties configProperties;

    @Override
    public ModelAndView searchUsersPost(HttpServletRequest request, HttpSession session, ViewUserForm viewUserForm,
            BindingResult result) {
        UserSearchCriteria criteria = (UserSearchCriteria) session.getAttribute("criteria");

        if (criteria == null) {
            criteria = new UserSearchCriteria();

            User userConnected = userService.getUserConnected();

            criteria.setLevel1UserID(userConnected.getId());
            criteria.setRoleId(roleService.getRoleId(RoleUtils.ROLE_PAYEE));
            session.setAttribute("criteria", criteria);
        }

        return searchUsers(request, criteria, viewUserForm, result);
    }

    @Override
    public ModelAndView updateUserList(HttpServletRequest request, HttpSession session, ViewUserForm viewUserForm,
                                       BindingResult result) {
        validateNumberOfActivePayees(viewUserForm, result);

        return super.updateUserList(request, session, viewUserForm, result);
    }

    private void validateNumberOfActivePayees(ViewUserForm viewUserForm, BindingResult result) {
        int max_payees = configProperties.getMaxPayeesPerSP();

        if (viewUserForm.getUsersListInGui() != null) {
            int delta = viewUserForm.getUsersListInGui().size() - viewUserForm.getInGuiTotal();

            if (delta > 0) {

                // This means we have new added inGui payees. Have to check if we overcome the limit.
                Page<User> payees = userService.findUsersByLevel1User(viewUserForm.getLevel1UserId(), 1, 65535, "id",
                                        "desc");
                int currentInGui = 0;

                for (User u : payees.getPageItems()) {
                    currentInGui += (u.getInGui()
                                     ? 1
                                     : 0);
                }

                if (currentInGui + delta > max_payees) {
                    result.reject("userlist.too.many.active.payees", new Object[] { max_payees }, "");
                }
            }
        }
    }

    @Override
    public ModelAndView createUser(EditUserForm editUserForm, BindingResult result) {
        validator.validate(editUserForm, result);
        validateEmailEfin(editUserForm, result);

        if (result.hasErrors()) {
            ModelAndView mav = new ModelAndView("/users/create_user");

            mav.addObject("elements", getElementsInstance());

            return mav;
        }

        editUserForm.setRoleId(roleService.getRoleByName(RoleUtils.ROLE_PAYEE).getId());
        editUserForm.setLevel1UserId(userService.getByEmail(SecurityContextUser.getUserName()).getId());
        this.createUser(editUserForm);

        return new ModelAndView("redirect:/users/view_users.htm");
    }

    @Override
    public ModelAndView viewUserDetails(int userId, Boolean saveSuccess) {
        User         user         = this.getUserDetailed(userId);
        ViewUserForm viewUserForm = new ViewUserForm(user);

        if (saveSuccess != null) {
            viewUserForm.setSaveSuccess(saveSuccess);
        }

        SPElements spElements    = (SPElements) getElementsInstance();
        User       userConnected = userService.getUserConnected();

        if (userConnected.getId().equals(user.getId()) && ((saveSuccess == null) ||!saveSuccess)) {
            spElements.setEditProfileMenu(SPElements.VISIBLE);
        }

        ModelAndView mav = new ModelAndView("/users/view_user_details");

        mav.addObject("viewUserForm", viewUserForm);
        mav.addObject("elements", spElements);

        return mav;
    }

    @Override
    public ModelAndView editUserDetails(HttpServletRequest request) {
        int userId;

        if (!StringUtils.isEmpty(request.getParameter("id"))) {
            userId = Integer.parseInt(request.getParameter("id"));
        } else {

            // Request comes from this.editMyUserDetails() function
            userId = userService.getUserConnected().getId();
        }

        User         user         = this.getUserDetailed(userId);
        EditUserForm editUserForm = new EditUserForm(user);
        User         currentUser  = userService.getUserConnected();

        currentUser.setRole(roleService.getRoleById(currentUser.getRole().getId()));
        editUserForm.setCurrentUser(currentUser);

        ModelAndView mav = new ModelAndView("/users/edit_user_details");

        mav.addObject("userForm", editUserForm);
        mav.addObject("level1Users", userService.findAll());
        mav.addObject("elements", getElementsInstance());

        return mav;
    }

    @Override
    public ModelAndView viewMyUserDetails() {
        User userConnected = userService.getUserConnected();

        return viewUserDetails(userConnected.getId(), false);
    }

    @Override
    public ModelAndView editMyUserDetails(HttpServletRequest request) {
        User userConnected = userService.getUserConnected();

        request.setAttribute("userId", userConnected.getId());

        return editUserDetails(request);
    }

    @Override
    public IElements getElementsInstance() {
        return new SPElements();
    }
}



